在 prisma client
中除了昨天介紹的透過 zod
在 prisma.$extends
中 validate query input
,以及透過 prisma.$extends.result
去 Computed fields
外,其實還有其他的功能,在 prisma.$extends
我們也可以客製化 model
的 methods
至於怎麼做到我們繼續看下去
一樣這是今天的 model
User
有 email
跟 password
欄位Password
model
去管理 user
model User {
id String @id @default(cuid())
email String
password Password?
}
model Password {
hash String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String @unique
}
我們今天的範例主要是做一個 user
註冊的功能,所以我們 User
model
才會有 email
以及 password
的欄位,通常我們在 create User
的時候,我們不會在 DB
直接存取 password
,取而代之的是我們會存 hash
過後的內容,以防止 user
的 password
被偷走,在 $extends
中我們實作 signUp
邏輯
這邊我們需要先 install bcryptjs
來幫我們 hash password
>npm i bcryptjs
>npm i --save-dev @types/bcryptjs
在 $extends.model
中我們可以自訂想要的 function
在特定的 model
裡,在 user.signUp
我們吃兩個參數 email
跟 password
,為了防止 user
的 password
存到 DB
,所以我們使用 bcrypt
幫我們 hash
password
,最後我們 return
create user
的結果
import bcrypt from 'bcryptjs'
const prismaClient = new PrismaClient().$extends({
model: {
user: {
signUp: async (email: string, password: string) => {
const hash = await bcrypt.hash(password, 10)
return prismaClient.user.create({
data: {
email,
password: {
create: {
hash
}
}
}
})
}
}
}
})
使用 signUp
這個 function
也很簡單,所有在 $extends.model
的內容,prisma client
都會自動幫你產生對應的 type
,使用起來非常方便
如此我們就成功 create
一個 user
了~
const user = await prismaClient.user.signUp('hiunji64@gmail.com', '123456')
{
user: { id: 'cm1te0z5r0000p581g6thkkqn', email: 'hiunji64@gmail.com' }
}
接著我們在定另外一個 function
,去找到使用特定 domain
當作 email
的 user
有哪些,如以下的 findManyByDomain
const prismaClient = new PrismaClient().$extends({
model: {
user: {
//..
findManyByDomain: (domain: string) => {
return prismaClient.user.findMany({
where: {
email: {
endsWith: `@${domain}`
}
}
})
}
}
}
})
如此我們就可以透過 findManyByDomain
拿查詢內容拉,是不是簡化非常多~
const userLists = await prismaClient.user.findManyByDomain('gmail.com')
{
userLists: [
{ id: 'cm1tcqxoz0000b1cl7j9dy9xb', email: 'hiunji64@gmail.com' }
]
}
最後我們再補充一個 signIn
來驗證 user
的 email
或是 password
是否正確,步驟如下:
findUser
有資料,代表 email
是正確的,沒有的話直接 return
user not found
bcrypt.compare
去驗證 findUser.password.hash
是否跟 input
的 password
是否一樣const prismaClient = new PrismaClient().$extends({
model: {
user: {
//..
signIn: async (email: string, password: string) => {
const findUser = await prismaClient.user.findFirst({
where: {
email
},
include: {
password: true
}
})
if (findUser === null) {
return 'user not found'
}
const verifyResult = await bcrypt.compare(password, findUser.password?.hash ?? '')
return {
verifyResult
}
}
}
}
})
接著我們測試一下如果 input
不存在的 email
,顯然有正確 return
user not found
const result = await prismaClient.user.signIn('aaa@gmail.com', '123456')
{ result: 'user not found' }
如果 email
正確蛋 password
錯誤,則 verifyResult
就是 false
const result = await prismaClient.user.signIn('hiunji64@gmail.com', '123456dd')
{ result: { verifyResult: false } }
反之如果 password
正確則驗證就成功了,之後就可以呼叫 prismaClient.user.signIn
去判斷 input
的來源是否正確~
const result = await prismaClient.user.signIn('hiunji64@gmail.com', '123456')
{ result: { verifyResult: true } }
以上就是今天的內容希望大家喜歡~
✅ 前端社群 :
https://lihi3.cc/kBe0Y